Guidance for Blacksmiths
Blacksmiths are vital to the success of Habitica. Your contributions are needed and appreciated! There are several ways to contribute coding expertise to the website and mobile apps. A great first step in getting acquainted with what needs to be done is joining the the Aspiring Coders guild to discuss programming for the site, learn some tips, and get ideas for what to work on. Be sure to also read Setting up Habitica Locally for important information about getting started. Ways to Help Website Below are tips for finding items to work on, depending on how you would like to contribute. In all cases, check the notes for the current status of the issue and whether anyone else is actively working on it (if a pull request is linked, someone has already submitted a fix). It is strongly recommended that before you start work, you post a comment on the GitHub issue or Trello card asking about the status of the item and expressing your interest in helping resolve it, and then wait a couple of days to see if there are any responses. This is because some issues and feature requests are not suitable for working on because Habitica's chief developers are currently making some large-scale changes to some parts of the code, which will partially or fully fix some issues. This is true even of the issues labelled with the labels listed below. If someone else has already recently commented to say they are working on an issue or Trello card, please leave the work for them. However if it's been many days since their last comment, they might no longer have time to contribute to Habitica, and then it could be appropriate for you to ask if you can take it over. Before starting work on an issue or feature, you might like to describe your suggested approach so that we can comment on whether it's suitable. * I want to start small: Check out the Github issue queue and search for items labeled priority - minor, priority - medium, and entry level coding for issues where you can ask to contribute. * I want to help where I'm most needed: Search for Github issues labeled help welcome now, priority - critical, and priority - important and ask to contribute before starting. * I want to create unit tests & Karma tests!: Welcome, bug-slayer! Please refer to the Tests section for further information. * I want to build things!: Make way for the new hero! Check out the Trello feature queue. It is important that you ask first to find out if a feature request you select is approved by the staff. Some feature suggestions are not suitable for implementation and a pull request that implements them would not be accepted. Mobile App for iOS * Please email mobile@habitica.com to discuss what work you'd like to do with our main mobile developers. * The iOS "Habitica" app has its own code base in its own GitHub repository at github.com/HabitRPG/habitrpg-ios. It is open source and contributions are welcome. * The old iOS "HabitRPG" app is no longer under development and contributions will not be accepted. Mobile App for Android * Please email mobile@habitica.com to discuss what work you'd like to do with our main mobile developers. * The Android "Habitica" app has its own code base in its own GitHub repository at github.com/HabitRPG/habitrpg-android. It is open source and contributions are welcome. * The old Android "HabitRPG" app is no longer under development and contributions will not be accepted. BountySource Some issues will have BountySource bounties on them, posted by staff or users. If your fix for such an issue is accepted, you will be able to claim the money as payment. In all other ways, these issues are treated identically to issues without bounties, so follow all the normal guidelines for them (e.g., asking first if it's okay for you to work on the issue). Website Technology Stack The technologies Habitica uses for its website are listed below. You don't need to be familiar with all of them, or even most of them, to be able to contribute! Some links to high-quality learning material are also included. Server Client Testing Services Working with a Local Installation Blacksmiths should create a local running instance of Habitica, for testing and development. The process to create a local instance can be difficult, so we've collected helpful tips for each operating system at Setting up Habitica Locally. Git Visit the Using Habitica Git page for a tutorial on how to fork the habitrpg repository, create new feature branches, manage commits and perform pull requests. MongoDB These are quick tips for new developers to get the hang of using the Mongo database. In the commands below, the $ sign indicates a Unix, Windows or Git Shell prompt and the > sign indicates a Mongo shell prompt. Type only the text that appears after $ or > into your command line. Access a shell Start the mongo shell then select the database: $ mongo > show dbs > use habitrpg Alternatively, directly start the shell with the correct database: $ mongo habitrpg Use the shell View the "collections" in the database ("users", "groups", etc): > show collections Find your test user and examine its data. From localhost settings, copy the User ID, then run this command: > db.users.find({_id: '85b007a2-b5b9-4bb4-8b82-e4567edb4919'})0 Want to see the preferences only? > db.users.find({_id: '85b007a2...'})0.preferences To update something for your user, use the update method with $set. For example, edit your profile blurb: > db.users.update({_id: '85b007a2...'}, {$set: {'profile.blurb':'test'}}) Give yourself 10 gems (can also be done from the Debug menu in the lower right of the footer): > db.users.update({_id: '85b007a2...'}, {$set: {'balance':10}}) Get admin rights (you will then see extra options in the Hall): > db.users.update({_id: '85b007a2...'}, {$set: {'contributor': {'admin':1}}}) Assign yourself unpurchasable quest scrolls (e.g., for limited edition quests): > db.users.update({_id: '85b007a2...'}, {$set: {'items.quests': {"egg":2,"basilist":1,"evilsanta":1,"evilsanta2":1}}}) This gives the user two Egg Hunt scrolls and one scroll each for another three quests. Please note that this will clear all other quest scrolls that the user possesses. Other scrolls can be added in the same way (respective keys can be found in common/script/content/index.js, although this file name is likely to change soon because the code is being refactored) or can be purchased later from the market. Use the debug-scripts In the debug-scripts directory (at the top level of the repository), there are scripts that allow you to modify your test accounts in various ways. To find out what each one does, read the code or run each script using node with no parameters to see a usage message. For example: node ./debug-scripts/grant-all-mounts.js Creating a local user account identical to your production site account Export your user data using the GET /user API route, and import it locally using MongoDB commands such as db.collection.insert(). This can be a fast way to create a local account prepopulated with tasks, equipment, currency and inventory. Your account will need to be inserted into the users collection, but this collection won't exist in Mongo until an account is created in your local install. To do this, start your local install and create a test account, and then insert your production account. The API does not export some authentication information for security reasons, so you will need to set it after inserting your user data. The command below sets the password to "test" and creates an API token: > db.users.update({'auth.local.username': 'your-username'}, {$set: {'auth.local.salt': '7eff6ff32a', 'auth.local.hashed_password': '5b5d5f748091e62aadf2f109f4a7379d2d8653dc', 'apiToken': '48ed9d70-0adf-431d-a001-1cb12d57590e'}}); Warning! Do not use the same API token or password that are used for your production site account! If you ever need to seek support for your local install or report information from it, you might include the full authentication data, and if it were the same as for your production account, the security of your production account would be compromised. The token used in the example above was randomly generated and is safe to use in your local install. Migrations Some Habitica website changes require existing user accounts to be modified (e.g., to assign a default value for a new setting to all users). Such database changes are done with a migration script, which contains JavaScript that connects to the database and makes modifications. All migration scripts are in migrations/. Read them and use them as examples to write your own script. The more recently edited scripts are likely to contain better, more up-to-date code than older scripts. To test a migration script: $ mongo habitrpg migrations/name_of_script.js Angular/Node/Jade Tips and Best Practices Data Binding, and Template Conditionals When working in the Jade templates, you may see element attributes such as ng-class, ng-show, or ng-if. These are bindings used to map model data to elements for display that are part of AngularJS. These bindings can be used to define styles or display elements based on conditionals. You may also notice some other attributes such as bo-class or bo-if.... so what's the difference? Bindings that begin with "ng" are part of Angular and are completely dynamic. This means every time something changes with the app, Angular will test all of these bindings with conditionals and take action again. Obviously this is a concern for performance. Sometimes the data used to calculate these conditionals will not change often, if ever. In that case, we have an option for static binding, using a library called Bindonce. These are similar bindings, but they are only checked at the initial load of the application.This is the preferred method of binding as long as the data will not change. Bindonce directives should only be used when the model data being used for the conditional will not change during a session, or will change infrequently enough that it's not unreasonable to expect the user to refresh the page. If this is not the case, then stick with traditional binding. If you can't decide or have no idea what you just read, just use the ng- attributes. Translatable Strings (locales files) Adding Translatable Strings To add a new translatable string in a template, it must be written in the jade file as follows: env.t("stringLabel") Then, in the common/locales/en directory, edit the json files, adding the new string as follows: 'lastLabel': 'Add a comma at the end of this line', 'stringLabel': 'String Title' } Do not update files in other directories under common/locales; translations are managed in Transifex. To test the string: * stop npm if it is running (Ctrl-C) * run npm start Modifying Translatable Strings Translatable strings appear in files in the common/locales/en directory. Each string consists of a key and a piece of text, for example: 'clearAll': 'clear all items', Do not change the key unless there's a very good reason to do so. Changing the text of a translatable string is acceptable, but the keys can be referenced elsewhere in Habitica's code. If the key is changed in one place, all the other locations would need to be updated as well. For example: if you needed to change 'clear all items' to 'delete all items', you would not also change 'clearAll' to 'deleteAll'. In addition, the keys that are used in the English translatable strings are also used throughout all the other languages directories under common/locales. When a piece of English text is changed without the key being changed, the other languages will keep using the existing translations for the original English text until the translators have had time to update the translations. Usually this is what you want because the existing translations are still good enough to be used. However if you were to change the key as well as the text, all the existing translations would no longer be used because the language files do not contain the new key. This would mean that people using languages other than English would see the new English text until the translators had time to provide strings for the new key. Tests Habitica has a suite of tests that can be run manually and automatically to help us detect bugs. When Habitica's admins deploy a new version of the website to production, the deployment process runs the tests and refuses to deploy the site if there are any failed tests. Before you make a pull request, it is recommended you run all existing tests to ensure your changes have not introduced any errors. If you are unable to run the tests, make a pull request anyway. Travis CI is used to run all the tests for every pull request. If any tests fail, Travis will report the results in your pull request and give a link you can use to view the test output. If the failed tests are caused by your code, it will be necessary to change the code before the pull request can be merged. Sometimes tests will fail for reasons not connected with new code, so if you are uncertain why the tests are failing, you can ask about the failing tests in your pull request comments. Most new code should have tests written for it before it can be merged into the code base. However, Habitica admins will help you write such tests, or -- time permitting -- write them for you if you are unable to do so. Do not be afraid to submit a pull request without tests, especially if you are not sure what is involved in the testing process, but please be aware that your submission might not be accepted until you or the admins have created the tests. Before running one test or the entire test suite on your local install, follow these steps: # Install gulp if it is not already installed, using npm install -g gulp If you are not sure whether gulp is installed, it is safe to run that command. # Ensure that mongod is running. # Stop any npm process such as npm start or any process that is already running the tests. Don't try to run two test processes at the same time. # Run killall node. This step is not always necessary, but if you have recently run tests and try to run them again, you might see errors such as "before all" hook: callee$2$0 and Error: connect ECONNREFUSED. Killing all node processes will prevent those errors. # Change directory into the top-level directory of your local install. To run the entire test suite locally: # Run npm test which is an alias for node_modules/.bin/gulp test, which prepares the test environment and runs all the test suites. To run a single test: #Run gulp test:nodemon in one terminal session. #Wait for it to get to info: Connected with Mongoose and then leave it running. #In another terminal session, run mocha test/SUBDIRECTORY/NAME_OF_TEST.js To run all tests in one subdirectory: #Run gulp test:nodemon in one terminal session. #Wait for it to get to info: Connected with Mongoose and then leave it running. #In another terminal session, run mocha test/SUBDIRECTORY --recursive To run the front-end tests: *Run npm run test:karma To run the lint tests: *Run npm run lint For more information about the API tests, see So you want to write API integration tests? Tests in Vagrant If you are running the tests in vagrant, you might see the following error: Error: /vagrant/.eslintrc: Configuration for rule "func-style" is invalid: Value "2,declaration,Object" has more items than allowed. or many instances of these: 1:1 error Definition for rule 'no-empty-pattern' was not found no-empty-pattern 1:1 error Definition for rule 'no-arrow-condition' was not found no-arrow-condition You might also find that this test starts but never completes: Starting 'test:e2e:safe'... A proper fix for these problems will be documented here soon, but as a short-term fix, you can avoid those problems by editing two files in the top-level directory of your local install. *Edit .eslintrc to comment out these lines: **"no-empty-pattern": 2, **"no-arrow-condition": 2, **"func-style": "declaration", { "allowArrowFunctions": true }, * Edit tasks/gulp-tests.js to comment out this line: **'test:e2e:safe', Do not commit those changes because those lines are needed for running tests on the server. Images For information about creating new images for Habitica, see Guidance for Artisans. When a new image has been prepared and approved by the staff, an issue will be created to request it be added to Habitica. A Blacksmith will then need to add it to the repository. Most images will need to be copied into suitable subdirectories under common/img/sprites After adding new images or new versions of existing images, run npm run sprites to recompile the image spritesheets. Sometimes, this command will result in a new spritesheet being created, in which case use git add to add the new files. You will find them under common/dist/sprites (look for a *.png and *.css file for each spritesheet). Other Useful Commands Here are various helpful commands. Search code In the console, type: grep -R "STRING" * To search for STRING in all files in the current directory and all the directories within it. To make a search case insensitive (STRING or String or string etc), add '-i' grep -iR "STRING" * You'll often want to search all files containing some keyword, in order to determine what files need to be edited when adding/editing some feature. The grep command also takes a regex as its search parameter: grep -R "REGEX" * Read more about grep and regex here. Search and replace Here is a perl command to run in the terminal: perl -e "s/FROM/TO/g" -pi $(find . -name "*.js") Replace FROM by the string you want to replace, and TO by the string to replace the first one with. Note that this example will replace that string only in javascript files (extension .js), but you can specify other filetypes if you want. If you want to replace all strings, but not their plural or other words containing that string (e.g. replace weapon by TEST, but do not replace weapons, do: perl -e 's/weapon\b/TEST/g' -pi * If you want to remove all lines in the javascript files that contain some keyword, do: perl -ni -e 'print unless /keyword/' -pi $(find . -name "*.js") These commands are particularly useful with translation-related work. Testing the Swagger API Interface Locally Habitica has an API interface, which uses the production database and code. When you have made your own local install of Habitica, you can test the local version of that interface at http://localhost:3000/static/api If your version of config.json was created a long time ago and you don't have the most up to date data from config.json.example, you might need to edit config.json to change the BASE_URL line to "BASE_URL":"http://localhost:3000" and then cancel and rerun the npm start command. Preference Settings Habitica has preference settings for the users to customize the website's behavior. New settings may be added if necessary. Please do not add settings only a small proportion of users are likely to use, or settings for trivial customizations. Instead choose a behavior the majority of users are likely to enjoy. Too many preferences makes the settings screen look cluttered and increases the appearance of complexity. If you're uncertain about whether a preference setting is desirable, you can discuss it in the Aspiring Coders guild or in a relevant Github issue or pull request. Tip for storing preferences When a new user preference setting is necessary, it can be added to website/src/models/user.js. Generally, the database will then pick them up the new setting automatically and add it to user accounts as necessary. If it is ever necessary for the database to be modified manually, admins can do that. "Information for Developers" Sections on General Wiki Pages At the bottom of some wiki pages, are sections called Information for Developers. These contain useful tips for Blacksmiths related to the content on that page. The information is hidden behind a spoiler-style show/hide toggle button so it doesn't clutter the page for non-technical users. The sections use the and templates to ensure correct formatting and wording for the buttons and other text. To see how that is done, open any page with an Information for Developers section in the source editor. To see a list of all pages with this section, use the "What links here" tool for the 'Start' template. To see all Information for Developers sections unhidden by default: * Create a Wikia account if you don't already have one. * Edit your personal Wikia css file, located at: http://habitica.wikia.com/wiki/User:YOUR_USERNAME_HERE/wikia.css * Insert these lines into CSS file: /* Force all "Information for Developers" sections to always be visible */ .habitrpg-InfoForDevs { display:block !important; } .habitrpg-InfoForDevs-hideIfDev { display:none; } You can see an example at User:LadyAlys/wikia.css Contributor Tier Process You're in luck! Blacksmiths do not need to do anything special, like complete a Contributor Tier request, in order to earn Contributor Tiers. Contributor Tiers will be granted by the admins as they review and accept Blacksmith submissions. Admins will track Blacksmith contributions for credit toward future Contributor Tiers. The first one or two Contributor Tiers are fairly easy to get and you might find that a single pull request is enough for each of them. The higher tiers require progressively more work and several pull requests might be needed. Admins will record each pull request as it is made and will award a tier when enough have been made. Category:Contributing